#include "sysinfowindowsimpl.h"

#include <windows.h>

SysInfoWindowsImpl::SysInfoWindowsImpl()
{

}

void SysInfoWindowsImpl::init()
{
    m_cpu_load_last_value = cpu_raw_data();
}

double SysInfoWindowsImpl::average_cpu_load()
{
    QVector<qulonglong> first_sample = m_cpu_load_last_value;
    QVector<qulonglong> second_sample = cpu_raw_data();
    m_cpu_load_last_value = second_sample;

    qulonglong current_idle = second_sample[0] - first_sample[0];
    qulonglong current_kernel = second_sample[1] - first_sample[1];
    qulonglong current_user = second_sample[2] - first_sample[2];
    qulonglong current_system = current_kernel + current_user;

    double percent = (current_system-current_idle)*100.0/current_system;
    return qBound(0.0, percent, 100.0);
}

double SysInfoWindowsImpl::memory_used()
{
    MEMORYSTATUSEX memory_status;
    memory_status.dwLength = sizeof(memory_status);
    GlobalMemoryStatusEx(&memory_status);
    qulonglong memory_physical_used = memory_status.ullTotalPhys - memory_status.ullAvailPhys;
    return (double)memory_physical_used/(double)memory_status.ullTotalPhys*100.0;
}

QVector<qulonglong> SysInfoWindowsImpl::cpu_raw_data()
{
    FILETIME idle_time;
    FILETIME kernel_time;
    FILETIME user_time;
    GetSystemTimes(&idle_time, &kernel_time, &user_time);

    QVector<qulonglong> raw_datas;
    raw_datas.append(convert_file_time(idle_time));
    raw_datas.append(convert_file_time(kernel_time));
    raw_datas.append(convert_file_time(user_time));
    return raw_datas;
}

qulonglong SysInfoWindowsImpl::convert_file_time(const FILETIME &file_time)
{
    ULARGE_INTEGER large_integer;
    large_integer.LowPart = file_time.dwLowDateTime;
    large_integer.HighPart = file_time.dwHighDateTime;
    return large_integer.QuadPart;
}
